﻿using Onshi.POS.Modelo.Entidades;
using Onshi.POS.Modelo.Enumeradores;
using Onshi.POS.Modelo.Objectos;
using Onshi.POS.Repositorios;
using Onshi.POS.Vendedores.Vistas;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;

namespace Onshi.POS.Vendedores
{
    public class VendedoresAltaModificacionPresentador
    {
        #region Constructores

        public VendedoresAltaModificacionPresentador(IVendedoresAltaModificacion vista)
        {
            this.vista = vista;
        }

        #endregion

        #region Atributos

        private IVendedoresAltaModificacion vista;

        #endregion

        #region Propiedades

        private RepositorioCamposPersonalizadosVendedores RepositorioCamposPersonalizadosVendedores
        {
            get { return new RepositorioCamposPersonalizadosVendedores(); }
        }

        private RepositorioEventos RepositorioEventos
        {
            get { return new RepositorioEventos(); }
        }

        private RepositorioVendedores RepositorioVendedores
        {
            get { return new RepositorioVendedores(); }
        }

        private RepositorioRubrosVendedores RepositorioRubrosVendedores
        {
            get { return new RepositorioRubrosVendedores(); }
        }

        private RepositorioTiposComisionesVendedores RepositorioTiposComisionesVendedores
        {
            get { return new RepositorioTiposComisionesVendedores(); }
        }

        private RepositorioTiposDomicilios RepositorioTiposDomicilios
        {
            get { return new RepositorioTiposDomicilios(); }
        }

        private RepositorioTiposTelefonos RepositorioTiposTelefonos
        {
            get { return new RepositorioTiposTelefonos(); }
        }

        private RepositorioBarrios RepositorioBarrios
        {
            get { return new RepositorioBarrios(); }
        }

        private RepositorioUsuarios RepositorioUsuarios
        {
            get { return new RepositorioUsuarios(); }
        }

        private RepositorioPermisos RepositorioPermisos
        {
            get { return new RepositorioPermisos(); }
        }

        private RepositorioRegistros RepositorioRegistros
        {
            get { return new RepositorioRegistros(); }
        }

        private RepositorioConfiguraciones RepositorioConfiguraciones
        {
            get { return new RepositorioConfiguraciones(); }
        }

        #endregion

        #region Metodos

        public void Inicializar()
        {
            var configuracion = RepositorioConfiguraciones.Devolver();
            if (configuracion == null)
                throw new Exception("La configuración no existe");
            vista.ConfiguracionImagen = configuracion.Imagen;
            if (vista.IdVendedor != 0)
            {
                var vendedor = RepositorioVendedores.DevolverPorId(vista.IdVendedor, true);
                if (vendedor == null)
                    throw new Exception("El vendedor no existe");
                if (vista.IdVendedor == (Int32)EnumVendedores.TitularDelComercio)
                    throw new Exception("El vendedor no se permite modificar");
                vista.Codigo = vendedor.Codigo;
                vista.Nombre = vendedor.Nombre;
                vista.IdRubroVendedor = vendedor.Rubro.Id;
                vista.IdTipoComisionVendedor = vendedor.TipoComision.Id;
                vista.Comision = vendedor.Comision;
                vista.ComisionMaxima = vendedor.ComisionMaxima;
                vista.Email = vendedor.Email;
                vista.SitioWeb = vendedor.SitioWeb;
                vista.Observaciones = vendedor.Observaciones;
                vista.Imagen = vendedor.Imagen;
                vista.ListadoDomicilios = vendedor.Domicilios;
                vista.ListadoTelefonos = vendedor.Telefonos;
                vista.ListadoCamposPersonalizados = vendedor.CamposPersonalizados;
            }
            else
            {
                vista.ListadoDomicilios = new List<DomicilioVendedor>();
                vista.ListadoTelefonos = new List<TelefonoVendedor>();
                var listadoCamposPersonalizados = new List<VendedorCampoPersonalizadoVendedor>();
                foreach (var item in RepositorioCamposPersonalizadosVendedores.DevolverTodos())
                    listadoCamposPersonalizados.Add(new VendedorCampoPersonalizadoVendedor()
                    {
                        Entidad = item,
                        Valor = String.Empty
                    });
                vista.ListadoCamposPersonalizados = listadoCamposPersonalizados;
            }
        }

        public void Aceptar()
        {
            var usuario = RepositorioUsuarios.DevolverPorId(vista.IdUsuarioSistema);
            if (usuario == null)
                throw new Exception("El usuario no existe");
            if (vista.IdVendedor == 0)
            {
                if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.VendedoresAlta))
                    throw new Exception("Permisos insuficientes");
            }
            else if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.VendedoresModificacion))
                throw new Exception("Permisos insuficientes");

            if (String.IsNullOrWhiteSpace(vista.Codigo))
                throw new Exception("El código no puede quedar vacío");
            if (String.IsNullOrWhiteSpace(vista.Nombre))
                throw new Exception("El nombre no puede quedar vacío");
            if (vista.IdRubroVendedor == 0)
                throw new Exception("El rubro de vendedor no puede quedar vacío");
            if (vista.IdTipoComisionVendedor == 0)
                throw new Exception("El tipo de comisión no puede quedar vacío");

            Vendedor vendedor;
            if (vista.IdVendedor != 0)
            {
                if (vista.IdVendedor == (Int32)EnumVendedores.TitularDelComercio)
                    throw new Exception("El vendedor no se permite modificar");
                vendedor = RepositorioVendedores.DevolverPorId(vista.IdVendedor, true);
                if (vendedor == null)
                    throw new Exception("El vendedor no existe");
            }
            else
                vendedor = new Vendedor();

            var vendedorCodigo = RepositorioVendedores.DevolverPorCodigo(vista.Codigo.Trim());
            if (vendedorCodigo != null)
                if (vista.IdVendedor != 0)
                {
                    if (vendedorCodigo.Id != vendedor.Id)
                        throw new Exception("Ya existe un vendedor con el mismo código");
                }
                else
                    throw new Exception("Ya existe un cliente con el mismo código");

            vendedor.TipoComision = RepositorioTiposComisionesVendedores.DevolverPorId(vista.IdTipoComisionVendedor);
            if (vendedor.TipoComision == null)
                throw new Exception("El tipo de comisión no existe");
            vendedor.Rubro = RepositorioRubrosVendedores.DevolverPorId(vista.IdRubroVendedor);
            if (vendedor.Rubro == null)
                throw new Exception("El rubro de vendedor no existe");

            vendedor.Codigo = vista.Codigo.Trim();
            vendedor.Nombre = vista.Nombre.Trim();

            switch ((EnumTiposComisionesVendedores)vendedor.TipoComision.Id)
            {
                case EnumTiposComisionesVendedores.SinComision:
                    vendedor.Comision = 0;
                    vendedor.ComisionMaxima = 0;
                    break;
                case EnumTiposComisionesVendedores.PorcentajeVenta:
                case EnumTiposComisionesVendedores.PorcentajeGanancia:
                    if (vista.Comision <= 0)
                        throw new Exception("La comisión no puede ser menor o igual a cero");
                    vendedor.Comision = vista.Comision;
                    if (vista.Comision < 0)
                        throw new Exception("La comisión maxima no puede ser menor a cero");
                    vendedor.ComisionMaxima = vista.ComisionMaxima;
                    break;
                case EnumTiposComisionesVendedores.MontoFijo:
                    if (vista.Comision <= 0)
                        throw new Exception("La comisión no puede ser menor o igual a cero");
                    vendedor.Comision = vista.Comision;
                    vendedor.ComisionMaxima = 0;
                    break;
                default:
                    break;
            }

            vendedor.Email = vista.Email.Trim();
            if (!String.IsNullOrWhiteSpace(vendedor.Email))
                if (!Validaciones.ValidarEmail(vendedor.Email))
                    throw new Exception("El mail es inválido");

            vendedor.SitioWeb = vista.SitioWeb.Trim();
            if (!String.IsNullOrWhiteSpace(vendedor.SitioWeb))
                if (vendedor.SitioWeb.Contains(' '))
                    throw new Exception("El sitio web es inválido");

            vendedor.Observaciones = vista.Observaciones.Trim();
            vendedor.Imagen = vista.Imagen;

            var registro = new Registro();
            registro.Usuario = usuario;
            if (vista.IdVendedor == 0)
                registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.VendedoresAlta);
            else
                registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.VendedoresModificacion);
            if (registro.Evento == null)
                throw new Exception("El evento no existe");

            if (vista.IdVendedor == 0)
                RepositorioVendedores.Insertar(vendedor);
            else
            {
                RepositorioVendedores.Modificar(vendedor);
                RepositorioVendedores.EliminarDomiciliosPorVendedor(vendedor);
                RepositorioVendedores.EliminarTelefonosPorVendedor(vendedor);
                RepositorioVendedores.EliminarCamposPersonalizadosPorVendedor(vendedor);
            }
            RepositorioRegistros.Insertar(registro, vendedor);

            foreach (var item in vista.ListadoDomicilios)
            {
                item.Barrio = RepositorioBarrios.DevolverPorId(item.Barrio.Id);
                item.Tipo = RepositorioTiposDomicilios.DevolverPorId(item.Tipo.Id);
                if (item.Tipo != null && item.Barrio != null)
                    RepositorioVendedores.InsertarDomicilio(vendedor, item);
            }

            foreach (var item in vista.ListadoTelefonos)
            {
                item.Tipo = RepositorioTiposTelefonos.DevolverPorId(item.Tipo.Id);
                if (item.Tipo != null)
                    RepositorioVendedores.InsertarTelefono(vendedor, item);
            }

            foreach (var item in vista.ListadoCamposPersonalizados)
                if (!String.IsNullOrWhiteSpace(item.Valor))
                {
                    item.Entidad = RepositorioCamposPersonalizadosVendedores.DevolverPorId(item.Entidad.Id);
                    if (item.Entidad != null)
                        RepositorioVendedores.InsertarCampoPersonalizado(vendedor, item);
                }
        }

        public void DomicilioAgregar()
        {
            if (String.IsNullOrWhiteSpace(vista.DomicilioCalle))
                throw new Exception("La calle no puede quedar vacía");
            if (String.IsNullOrWhiteSpace(vista.DomicilioNumero))
                throw new Exception("El número no puede quedar vacío");
            if (vista.DomicilioIdTipoDomicilio == 0)
                throw new Exception("El tipo de domicilio no puede quedar vacío");
            if (vista.DomicilioIdBarrio == 0)
                throw new Exception("El barrio no puede quedar vacío");
            var barrio = RepositorioBarrios.DevolverPorId(vista.DomicilioIdBarrio);
            if (barrio == null)
                throw new Exception("El barrio no existe");
            var tipo = RepositorioTiposDomicilios.DevolverPorId(vista.DomicilioIdTipoDomicilio);
            if (tipo == null)
                throw new Exception("El tipo de domicilio no existe");

            var lista = vista.ListadoDomicilios.ToList();
            var contador = 1;
            foreach (var item in lista)
            {
                item.Id = contador;
                contador++;
            }
            var domicilio = new DomicilioVendedor();
            domicilio.Id = contador;
            domicilio.Tipo = tipo;
            domicilio.Barrio = barrio;
            domicilio.Calle = vista.DomicilioCalle.Trim();
            domicilio.Numero = vista.DomicilioNumero.Trim();
            domicilio.Piso = vista.DomicilioPiso.Trim();
            domicilio.Departamento = vista.DomicilioDepartamento.Trim();
            lista.Add(domicilio);
            vista.ListadoDomicilios = lista;
        }

        public void DomicilioQuitar()
        {
            var lista = vista.ListadoDomicilios.ToList();
            lista.Remove(lista.SingleOrDefault(x => x.Id == vista.DomicilioId));
            vista.ListadoDomicilios = lista;
        }

        public void DomicilioEditar()
        {
            if (String.IsNullOrWhiteSpace(vista.DomicilioCalle))
                throw new Exception("La calle no puede quedar vacía");
            if (String.IsNullOrWhiteSpace(vista.DomicilioNumero))
                throw new Exception("El número no puede quedar vacío");
            if (vista.DomicilioIdTipoDomicilio == 0)
                throw new Exception("El tipo de domicilio no puede quedar vacío");
            if (vista.DomicilioIdBarrio == 0)
                throw new Exception("El barrio no puede quedar vacío");
            var barrio = RepositorioBarrios.DevolverPorId(vista.DomicilioIdBarrio);
            if (barrio == null)
                throw new Exception("El barrio no existe");
            var tipo = RepositorioTiposDomicilios.DevolverPorId(vista.DomicilioIdTipoDomicilio);
            if (tipo == null)
                throw new Exception("El tipo de domicilio no existe");

            var lista = vista.ListadoDomicilios.ToList();
            foreach (var item in lista)
                if (item.Id == vista.DomicilioId)
                {
                    item.Tipo = tipo;
                    item.Barrio = barrio;
                    item.Calle = vista.DomicilioCalle.Trim();
                    item.Numero = vista.DomicilioNumero.Trim();
                    item.Piso = vista.DomicilioPiso.Trim();
                    item.Departamento = vista.DomicilioDepartamento.Trim();
                }
            vista.ListadoDomicilios = lista;
        }

        public void TelefonoAgregar()
        {
            if (String.IsNullOrWhiteSpace(vista.TelefonoCodigoArea))
                throw new Exception("La código de área no puede quedar vacío");
            if (String.IsNullOrWhiteSpace(vista.TelefonoNumero))
                throw new Exception("El número no puede quedar vacío");
            if (vista.TelefonoIdTipoTelefono == 0)
                throw new Exception("El tipo de teléfono no puede quedar vacío");
            var tipo = RepositorioTiposTelefonos.DevolverPorId(vista.TelefonoIdTipoTelefono);
            if (tipo == null)
                throw new Exception("El tipo de teléfono no existe");

            var lista = vista.ListadoTelefonos.ToList();
            var contador = 1;
            foreach (var item in lista)
            {
                item.Id = contador;
                contador++;
            }
            var telefono = new TelefonoVendedor();
            telefono.Id = contador;
            telefono.Tipo = tipo;
            telefono.CodigoArea = vista.TelefonoCodigoArea.Trim();
            telefono.Numero = vista.TelefonoNumero.Trim();
            lista.Add(telefono);
            vista.ListadoTelefonos = lista;
        }

        public void TelefonoQuitar()
        {
            var lista = vista.ListadoTelefonos.ToList();
            lista.Remove(lista.SingleOrDefault(x => x.Id == vista.TelefonoId));
            vista.ListadoTelefonos = lista;
        }

        public void TelefonoEditar()
        {
            if (String.IsNullOrWhiteSpace(vista.TelefonoCodigoArea))
                throw new Exception("La código de área no puede quedar vacío");
            if (String.IsNullOrWhiteSpace(vista.TelefonoNumero))
                throw new Exception("El número no puede quedar vacío");
            if (vista.TelefonoIdTipoTelefono == 0)
                throw new Exception("El tipo de teléfono no puede quedar vacío");
            var tipo = RepositorioTiposTelefonos.DevolverPorId(vista.TelefonoIdTipoTelefono);
            if (tipo == null)
                throw new Exception("El tipo de teléfono no existe");

            var lista = vista.ListadoTelefonos.ToList();
            foreach (var item in lista)
                if (item.Id == vista.TelefonoId)
                {
                    item.Tipo = tipo;
                    item.CodigoArea = vista.TelefonoCodigoArea.Trim();
                    item.Numero = vista.TelefonoNumero.Trim();
                }
            vista.ListadoTelefonos = lista;
        }

        #endregion
    }
}
